package com.huitone.smspfm.interfacz.mo;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.codec.binary.Base64;

import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.interfacz.logger.ExtLogger;
import com.huitone.smspfm.interfacz.core.AppStaticConfigs;
import com.huitone.smspfm.interfacz.dao.entity.SvrNodeDef;
import com.huitone.smspfm.socket.client.SmsClient;

/**   
* @Title SrvNodeSocketManager.java 
* @Package com.huitone.smspfm.interfacz.delrep 
* @Description TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年4月4日 下午11:55:02 
* @version V1.0   
*/
public class SvrNodeClientsManager {
	
	private static final ExtLogger logger = ExtLogger.create(SvrNodeClientsManager.class);
	
	private Map<String, SmsClient> map = new ConcurrentHashMap<>();
	
	// 最大空闲时间
	private long maxFreeTimeMillinsToClear = 30000;
	
	// 守护狗的执行时间间隔
	private long watchDogDelay = 5000;
	
	private SocketClientWatchDog socketClientWatchDog = null;
	
	private DelRepMessageHandler delRepMessageHandler = null;

	private static SvrNodeClientsManager instance = new SvrNodeClientsManager();
	
	public static SvrNodeClientsManager getInstance() {
		return instance;
	}
	
	private SvrNodeClientsManager() {
		delRepMessageHandler = new DelRepMessageHandler();
	}
	
	/**
	 * 获取对应业务端编号的客户端
	 * @param srvNode
	 * @return
	 */
	public synchronized SmsClient getSvrNodeClient(String srvNode) {
		
		if (socketClientWatchDog == null) {
			socketClientWatchDog = new SocketClientWatchDog(this).setDelay(watchDogDelay);
			socketClientWatchDog.start();
		}
		
		SmsClient result = null;
		
		if (!StringUtils.isEmpty(srvNode)) {
			
			if (map.containsKey(srvNode) && map.get(srvNode) != null) {
				logger.debug("SvrNodeClientsManager包含了该客户端连接:" + srvNode);
				result = map.get(srvNode);
			} else {
				logger.debug("SvrNodeClientsManager没有包含该客户端,新增客户端连接:"+ srvNode);
				result = create(srvNode);
				if (result != null) {
					map.put(srvNode, result);
				}
			}
		}
		
		return result;
	}
	
	/**
	 * 查找业务端定义表,根据定义表信息创建客户端
	 * @param srvNode
	 * @return
	 */
	private SmsClient create(String srvNode) {
		
		SvrNodeDef svrNodeDef = AppStaticConfigs.svrNodeDefMap.get(srvNode);
		
		if (svrNodeDef != null) {
			
			SmsClient client = new SmsClient();
			client.setSrvNode(srvNode);
			client.setServerIp(svrNodeDef.getServerIp());
			client.setServerPort(StringUtils.toIntegerP(svrNodeDef.getServerPort()));
			client.setLoginName(svrNodeDef.getLoginSvrUser());
			client.setLoginPass(new String(Base64.decodeBase64(svrNodeDef.getLoginSvrPwd())));
			client.setMessageHandler(delRepMessageHandler);
			return client;
		}
		
		return null;
	}
	
	/**
	 * 清空所有客户端
	 */
	public synchronized void clear() {
		
		Iterator<Entry<String, SmsClient>> iterator = map.entrySet().iterator();
		
		while(iterator.hasNext()) {
			SmsClient svrNodeClient = iterator.next().getValue();
			svrNodeClient.destory();
		}
		
		map.clear();
	}
	
	public synchronized void removeOutTimes() {
		
		Iterator<Entry<String, SmsClient>> iterator = map.entrySet().iterator();
		
		while(iterator.hasNext()) {
			
			Entry<String, SmsClient> entry = iterator.next();
			//String srvNode = entry.getKey();
			SmsClient client = entry.getValue();
			
			if (client != null) {
				
				long currentTimeMillis = System.currentTimeMillis();
				
				if ((currentTimeMillis - client.getLastReadTimeMillis()) >= maxFreeTimeMillinsToClear) {
					logger.debug("SvrNodeClientsManager移除超时客户端:" + client.getSrvNode());
					client.destory();
					iterator.remove();
				}
				
			} else {
				iterator.remove();
			}
		}
	}
	
	public void destroy() {
		
		if (delRepMessageHandler != null) {
			delRepMessageHandler.destroy();
			delRepMessageHandler = null;
		}
		
		if (socketClientWatchDog != null) {
			socketClientWatchDog.destroy();
			socketClientWatchDog = null;
		}
		
		clear();
	}
	
	class SocketClientWatchDog extends Thread {
		
		private long delay = 60000;
		
		private boolean keepGoing = true;
		
		private SvrNodeClientsManager svrNodeClientsManager = null;
		
		public SocketClientWatchDog(SvrNodeClientsManager svrNodeClientsManager) {
			this.svrNodeClientsManager = svrNodeClientsManager;
		}
		
		@Override
		public void run() {
			
			int countToExcute = (int) (delay / 1000);
			int count = 0;
			
			while (!this.isInterrupted() && isKeepGoing()) {
				
				if (count >= countToExcute) {
					if (svrNodeClientsManager != null) {
						svrNodeClientsManager.removeOutTimes();
					}
					count = 0;
				} else {
					count ++;
				}
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					break;
				}
			}
		}

		public SocketClientWatchDog setDelay(long delay) {
			this.delay = delay;
			return this;
		}

		public boolean isKeepGoing() {
			return keepGoing;
		}

		public void setKeepGoing(boolean keepGoing) {
			this.keepGoing = keepGoing;
		}

		@Override
		public void destroy() {
			this.setKeepGoing(false);
			this.interrupt();
		}
	}
}
